﻿#include <string>
#include <stdlib.h>
#include <list>
#include <vector>
#include <algorithm>
#include<time.h>
#include <iostream>
#include <winsock2.h>
#include "sha1.h"
#include "base64.h"

#pragma comment(lib,"WS2_32")

#include <string.h>
using namespace std;

int *CharToBinary(char*,int);
char *BinaryToChar(int*,int );

char* match_string(const char* src, const char* pattern, char end);

void update_dot(SOCKET *,int );

const int MAX=100;

int main(int argc, char* argv[])
{
	list<int >numbers;
	list<int >::iterator num;
	
	vector<int *>height;
	list<int *>::iterator heightIterator;
	int a=1,b=2,c=4;
	height.push_back(&a);
	height.push_back(&b);
	b=7;
	height.push_back(&c);
	
	for (int i=0,j=1255;i <3;i++)
	{
		int d=i+6;
		numbers.push_back(d);
		cout<<"j: "<<j<<endl;
	}
	
	for (num=numbers.begin();num!=numbers.end();++num)
	{
		cout << *num << endl<<endl;
	}
	
	int n=25438;
	char msg2[10],msg1[100]="dot ";
	sprintf(msg2,"%d",n);
	
	strcat(msg2," has changed.");
	strcat(msg1,msg2);
	
	cout <<"msg1: "<<msg1<<endl;
	cout <<"size of msg1: "<<sizeof(msg1)<<endl;
	
	//排序功能测试
	int cc[20]={2,4,1,23,5,76,0,43,24,65};
	for(int i=0;i<20;i++)
	cout<<cc[i]<<" ";
	cout <<endl;
	sort(cc,cc+20,less<int>());
	for(int i=0;i<20;i++)
	cout<<cc[i]<<" ";
	cout <<endl;
	
	int port=6666;char *wsurl="/ws";
	char* pHandshake = "HTTP/1.1 101 Web Socket Protocol Handshake\r\n"
	"Upgrade: WebSocket\r\n"
	"Connection: Upgrade\r\n"
	"WebSocket-Origin: http://localhost:%d\r\n"
	"Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n"
	"WebSocket-Location: ws://localhost:%d%s\r\n\r\n";
	char head[1024]={0};
	sprintf_s(head,1024,pHandshake,port,port,wsurl);
	cout<<head<<endl;
	char end=0x20;
	if (end== ' ')
	{
		cout << "end:"<<end <<"aaaa"<< endl;
	}
	
	char* origin = match_string(pHandshake, "Sec-WebSocket-Key: ", '\0');
	cout<<"key: "<< origin<<endl;
	string keyy = origin;
	cout<< keyy<<endl;
	
	//key转换
	std::string server_key = "7V8vqsRJExoRbyFnw7F0vw==";
	server_key += "258EAFA5-E914-47DA-95CA-C5AB0DC85B11";
	cout << "server_key:" << server_key <<endl;
	SHA1 sha;
	unsigned int message_digest[5];

	sha.Reset();
	sha << server_key.c_str();

	sha.Result(message_digest);
	// convert sha1 hash bytes to network byte order because this sha1
	//  library works on ints rather than bytes
	for (int i = 0; i < 5; i++) {
		message_digest[i] = htonl(message_digest[i]);
	}

	server_key = base64_encode(
	reinterpret_cast<const unsigned char*>
	(message_digest),20
	);
	
	cout << "server_key:" << server_key <<endl;
	cout << "server_key:" << server_key <<endl;
	//转换成功
	
	char *s="中";
	char *q=s;
	int m =0;
	for(;*q!=0;q++)
	{
		for ( m=7;m>=0;m--)
		{
			unsigned char a=0;
			unsigned char b=0x01;
			a=( (*q)>>m )&b; /*可见内循环*p的值是不变的 */
			printf("%u",a);
		}
	}
	cout <<endl;
	for (m=0;s[m]!='\0';m++)
	;
	//++m;
	for (int i=0;i<m;i++)
	{
		printf("%4x\n",s[i]);
	}
	cout<<"m:"<<m<<endl<<endl;
	
	int *iTemp;
	iTemp = CharToBinary(s,m);
	for (int i=0;i < m*8;i++)
	{
		cout << iTemp[i]<<" ";
		if (i%8==0&&i!=0)
		{
			cout << " ";
		}
		
	}
	cout <<endl;
	char *cTemp;
	cTemp = BinaryToChar(iTemp,m*8);
	cout << cTemp <<endl;
	
	
	/* //随机数部分
	cout<<"输出10个随机数，在0到999之间"<<endl;
	srand((unsigned)time(NULL));
	for(int i=1;i>0;i++){
	Sleep(300);
	cout<<rand()%MAX<<endl;} */
	int aa[10],bb[100];
	int low=101,up=200,length_a=10,sub,length_b=100,tmp;
	srand((unsigned)time(NULL));
	for (int i=0;i<up-low+1;i++)
	{
		bb[i]=low+i-1;
	}
	for (int i=0;i<length_a;i++)
	{
		sub=rand()%length_b;
		tmp=bb[sub];
		bb[sub]=bb[length_b-1];
		length_b--;
		aa[i]=tmp;
	}
	for (int i=0;i<10;i++)
	{
		cout << "aa[i]: "<<aa[i]<<endl;
	}
	
	for (int i =0; i < height.size();++i)
	{
		cout << *height[i]<< endl;
	}
	list<string> Milkshakes;
	list<string>::iterator MilkshakeIterator;//为Milkshakes实例容器定义一个iterator指针：MilkshakeIterator
	Milkshakes.push_back("Chocolate");
	Milkshakes.push_back("Strawberry");
	Milkshakes.push_front("Lime");
	Milkshakes.push_front("Vanilla");

	// print the milkshakes打印
	Milkshakes.push_front("The Milkshake Menu");
	Milkshakes.push_back("*** Thats the end ***");
	for (MilkshakeIterator=Milkshakes.begin(); MilkshakeIterator!=Milkshakes.end(); ++MilkshakeIterator) 
	{// dereference the iterator to get the element
		cout << *MilkshakeIterator << endl; //输出	
	}
	cout<< Milkshakes.size()<<endl;
	cout<< Milkshakes.max_size()<<endl;
	
	SOCKET all_dots[1000][30];
	cout<< "sizeof(all_dots): "<< sizeof(all_dots)<<endl;
	
	typedef struct info{
		int length;
		int dots[1000];		
	}info;
	info sturct_dots;
	cout<<"input dots(end with 0):"<<endl;
	int number;
	for (number=0 ; number<1000;number++)
	{
		int j;
		cin>>j;
		if(j==0) break;
		sturct_dots.dots[number]=j;
	}
	sturct_dots.length=number;
	cout<< "number of dots: "<<sturct_dots.length<<endl;
	cout << "length of sturct_dots: "<< sizeof(sturct_dots)<<endl;
	for (int i=0 ; i<sturct_dots.length;i++)
	{
		cout<< sturct_dots.dots[i]<<endl;
	}
	
	//cout << endl<< "length of info: "<< sizeof(info1)<<endl;
	int leng=10;
	//cin>> leng;
	int *p=new int[leng];
	int *nums = (int *)malloc(sizeof(int) * 1000);
	cout << endl<< "length of array: "<< sizeof(p[1])<<endl;
	cout << endl<< "length of num: "<< sizeof(nums)<<endl;
	
	char ss[100];
	cout<< "sizeof of ss: "<< sizeof(ss)<<endl;
	return 0;
}

/* typedef struct{
	SOCKET sockClient;
	int dot[100];
}sClient_info,*p_sClient_info;

list<p_sClient_info> sClient_info_list;

sClient_info sClient1;
sClient1.sockClient=sClient;

sClient_info_list.push_back(sClient1); */

/* closesocket(sockArray[i]);

cout << "Find the client closing."<< endl;
//从list中删去该客户端					
for (sClient_iterator=sClient_info_list.begin();sClient_iterator!=sClient_info_list.end();sClient_iterator++)
{
	if((*sClient_iterator).sockClient==sockArray[i])
	{
		cout << "Clinet " << i << " closed."<< endl;
		sClient_info_list.erase(sClient_iterator);
		break;
	}
}
	
for (int j=i;j<nEventTotal-1;j++)
{
	sockArray[j]=sockArray[j+1];
	eventArray[j] = eventArray[j+1];
}
	nEventTotal--;
	cout<< sClient_info_list.size() <<" client in the list. " << nEventTotal <<" socket in the array." << endl; */

//线程的入口函数， 监控点位变化并发给客户端
/* DWORD WINAPI Dots_Change(LPVOID lpParameter)//thread data
{
	Sleep(8000);
	while(true)
	{
		Sleep(10);
		srand((unsigned)time(NULL));
		int j=rand()%MAX;
		WaitForSingleObject(hMutex,INFINITE);
		update_dot(all_dots[j],j);
		ReleaseMutex(hMutex);
	}
	return 0;
	
}

void update_dot(SOCKET *dot_sockets1,int j)
{
	SOCKET *dot_sockets=dot_sockets1;//第j+1号点下面注册的客户端们
	int dot_j=j+1;//j+1号点
	if (dot_sockets[0]!=INVALID_SOCKET)
	{
		for (int k=0;k<30;k++)
		{									
			if (dot_sockets[k]==INVALID_SOCKET)
			{
				//cout<<all_dots[j][k]<<" ";
				break;
			}
			//else cout<<all_dots[j][k]<<" ";
			else {
				char msg1[20],msg[100]="dot ";
				sprintf(msg1,"%d",dot_j);
				
				strcat(msg1," has changed.");
				strcat(msg,msg1);
				send(dot_sockets[k],msg,sizeof(msg),0);
			}
		}
	}
}
*/


char* match_string(const char* src, const char* pattern, char end)
{
	char buf[BUFSIZ];
	memset(buf, 0, BUFSIZ);
	size_t src_len = strlen(src); 
	size_t ptn_len = strlen(pattern);
	unsigned short b=0, p=0, i=0; 
	char c='\0';
	for(i=0; i<src_len; i++)
	{
		c = src[i];
		if(p==ptn_len)
		{ // p==ptn_len 表示正在匹配中
			if(c=='\r' || c=='\n'  || (end !='\0' && c==end) ) 
			{
				p++; // 匹配结束
			} else
			{
				buf[b++]=c; // 匹配到的字符 
			}
		}else if(p<ptn_len)
		{    // 为达到匹配要求
			if(c==pattern[p])
			{
				p++;
			}
			else 
			{
				p=0;
			}
		}
	}
	size_t ret_len = strlen(buf);
	char *ret_p; 
	if( ret_len>0 )
	{
		ret_p = (char*)calloc(ret_len+1,sizeof(char)); // 加 1 为了存储 '\0'
		memcpy(ret_p, buf, ret_len);
	} else 
	{
		ret_p = NULL;
	}
	return ret_p; 
}

/* void HexDump(int cn,char *buf,int len) {
	int i,j,k;
	char binstr[80];

	Lock(&cs_HEX);
	for (i=0;i<len;i++) {
		if (0==(i%16)) {
			sprintf(binstr,"%03d %04x -",cn,i);
			sprintf(binstr,"%s %02x",binstr,(unsigned char)buf[i]);
		} else if (15==(i%16)) {
			sprintf(binstr,"%s %02x",binstr,(unsigned char)buf[i]);
			sprintf(binstr,"%s  ",binstr);
			for (j=i-15;j<=i;j++) {
				sprintf(binstr,"%s%c",binstr,('!'<buf[j]&&buf[j]<='~')?buf[j]:'.');
			}
			Log("%s\n",binstr);
		} else {
			sprintf(binstr,"%s %02x",binstr,(unsigned char)buf[i]);
		}
	}
	if (0!=(i%16)) {
		k=16-(i%16);
		for (j=0;j<k;j++) {
			sprintf(binstr,"%s   ",binstr);
		}
		sprintf(binstr,"%s  ",binstr);
		k=16-k;
		for (j=i-k;j<i;j++) {
			sprintf(binstr,"%s%c",binstr,('!'<buf[j]&&buf[j]<='~')?buf[j]:'.');
		}
		Log("%s\n",binstr);
	}
	Unlock(&cs_HEX);
}
*/

int *CharToBinary(char cData[],int length)
{
	int len= length;
	int *iBufBinary =new int[len];
	int i,j;
	
	for(i = 0; i < len; i++)
	{
		for( j = 0; j < 8; j++)
		{
			if( cData[i]&(0x80>>j))
			{
				iBufBinary[i*8+j]=1;
			} 
			else
			{
				iBufBinary[i*8+j]=0;
			}
		}
	}
	return iBufBinary;
}

//二进制转换为字符串
char *BinaryToChar(int bData[],int length)
{
	int len=length/8;
	cout<<"length: "<<length<<" len: "<<len<<endl;
	char* iBufChar = new char[len+1];
	int i,tmp1,tmp2;
	cout<<"进入函数"<<endl;
	for (int j=0;j < length;j++)
	{
		cout << bData[j]<<" ";
		if (j%8==0&&j!=0)
		{
			cout << " ";
		}
		
	}
	
	for (i=0;i<len;i++)
	{
		tmp1 = bData[i*8]*128+bData[i*8+1]*64+bData[i*8+2]*32+bData[i*8+3]*16+bData[i*8+4]*8+bData[i*8+5]*4+bData[i*8+6]*2+bData[i*8+7]*1;
		//cout<<"bData[i]: "<<bData[i]<<endl;
		cout<<"tmp1: "<<tmp1<<endl;
		//tmp2=tmp1-48; //'0'的ascii码为48
		//cout<<"tmp2: "<<tmp2<<endl;
		iBufChar[i]='0'+tmp1-48;
	}
	iBufChar[len]='\0';
	return iBufChar;
}


char *get_websocket_accept(char *buff)//buff为客户端发送的原始握手信息
{
	struct handshake hs = {NULL,NULL,NULL,NULL,NULL,NULL};
	handshake_test(buff,&hs);				
	string value= hs.key;
	cout << "key: "<< value <<endl;
	value+="258EAFA5-E914-47DA-95CA-C5AB0DC85B11";
	//key convert
	SHA1 sha;
	unsigned int message_digest[5];

	sha.Reset();
	sha << value.c_str();

	sha.Result(message_digest);
	// convert sha1 hash bytes to network byte order because this sha1
	//  library works on ints rather than bytes
	for (int j = 0; j < 5; j++) {
		message_digest[j] = htonl(message_digest[j]);
		cout<<"message_digest:"<<message_digest[j]<<endl;
	}

	value = base64_encode(
	reinterpret_cast<const unsigned char*>
	(message_digest),20
	);
	
	cout << "key after convert:" << value <<endl<<endl;
	char* res=new char[1024];
	strcpy(res,value.c_str());
	
	char* buffer=new char[1024];
	
	sprintf(buffer,"HTTP/1.1 101 Switching Protocols\r\n"
	"Upgrade: WebSocket\r\n"
	"Connection: Upgrade\r\n"
	"Sec-WebSocket-Accept: %s\r\n\r\n",res);
	
	free_handshake(&hs);
	return res;
}

bool close_from_list(SOCKET sock,int i)
{
	closesocket(sock);
	for (sClient_iterator=sClient_info_list.begin();sClient_iterator!=sClient_info_list.end();sClient_iterator++)
	{
		if((*sClient_iterator).sockClient==sock)
		{
			cout << "Clinet " << i << " closed."<< endl;
			Sleep(1);
			WaitForSingleObject(hMutex,INFINITE);
			for (int j=0,tmp_dot=0; j<(*sClient_iterator).num; j++)
			{
				tmp_dot=(*sClient_iterator).dot[j];
				for (int k=0; k<30; k++)
				{
					if (all_dots[tmp_dot-1][k]==sock)
					{
						for (;k<29;k++)
						{
							all_dots[tmp_dot-1][k]=all_dots[tmp_dot-1][k+1];
						}
						break;
					}
				}
			}
			ReleaseMutex(hMutex);
			sClient_info_list.erase(sClient_iterator);
			break;
		}
	}
	return true;
}

for (sClient_iterator=sClient_info_list.begin();sClient_iterator!=sClient_info_list.end();sClient_iterator++)
{
	if((*sClient_iterator).sockClient==sockArray[i])
	{
		cout << "find the client in the list"<< endl;
		int ndots=0;//客户端注册点位数量
		for (int j=0;message[j]!='\0';j++)
		{								
			char tmp[5];
			int k=0;
			for (;message[j]!=';'&&message[j]!='\0';j++,k++)
			{
				tmp[k]=message[j];
			}
			tmp[k]='\0';
			WaitForSingleObject(hMutex,INFINITE);
			d=1;
			
			//WaitForSingleObject(hMutex,INFINITE);
			tmp_dot=(*sClient_iterator).dot[ndots]=atoi(tmp);//整型串转换成int
			for (int k=0; k<30; k++)
			{
				if (all_dots[tmp_dot-1][k]==INVALID_SOCKET)
				{
					all_dots[tmp_dot-1][k]=sockArray[i];
					all_dots[tmp_dot-1][k+1]=INVALID_SOCKET;
					//ReleaseMutex(hMutex);
					break;
				}
				//ReleaseMutex(hMutex);
			}
			ReleaseMutex(hMutex);
			(*sClient_iterator).num=++ndots;
		}
	}
}